package cn.happyjava.springbootsecurity.config;

import cn.happyjava.springbootsecurity.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.stream.Collectors;

/**
 * @Author: zlxiao
 * @Date: 2019/9/8 14:09
 */
@Component
public class ApiKeyAuthenticationManager implements AuthenticationManager {

    @Autowired
    private UserService userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String apiKey = (String) authentication.getCredentials();
        if (StringUtils.isNotBlank(apiKey)) {
            String login = null;
            Collection<String> authorities = null;

            if (StringUtils.isBlank(login) || authorities == null) {

                UserDetails user = userDetailsService.findByApiKey(apiKey);
                if (user != null) {
                    login = user.getUsername();
                    if (!user.isAccountNonLocked()) {
                        //throw new UserNotActivatedException("User " + login + " is not activated");
                    }

                    if (!user.isEnabled()) {
                        // throw new UserNotEnabledException("User " + login + " is disabled");
                    }

                    authorities = user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
                    if (StringUtils.isNotBlank(login) && authorities != null) {
                    }
                }
            }

            if (StringUtils.isNotBlank(login) && authorities != null) {
                return new CommonAuthentication(login, authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet()));
            } else {
                throw new BadCredentialsException("Authentication failed with invalid api key " + apiKey);
            }
        } else {
            return null;
        }
    }
}
